package service

import (
	"encoding/json"

	"chat.com/common"
	"chat.com/library"
	"chat.com/model"
	"chat.com/pkg/logger"
	"chat.com/server/grpc/grpcclient"
	"chat.com/server/wsserver/connection"
)

/* 单聊消息服务 */

type SendResult struct {
	Success bool
	MsgId   int64
}

type PersistSingleChatMsgResult struct {
	Success bool
	MsgId   int64
}

// 1. 持久化单聊消息
func PersistSingleChatMessage(req *common.WsSingleChatRequest) (code int64, result *PersistSingleChatMsgResult, errReturn error) {
	logger.Debug("Enter PersistSingleChatMessage")
	defer logger.Debug("Exit PersistSingleChatMessage")

	// 验证好友关系
	if ok, err := isSingleFriend(req.SenderId, req.RecieverId); !ok {
		code = common.NotFriend
		result = nil
		errReturn = err
		return
	}

	// 历史消息存储
	msgId, err := persistSingleChatMessage(req)
	if err != nil {
		code = common.StoreError
		result = nil
		errReturn = err
		return
	}

	code = common.OK
	result.MsgId = msgId
	return
}

// 发送单聊消息
func SendSingleChatMessage(req *common.WsSingleChatRequest) (code int64, result *PersistSingleChatMsgResult, errReturn error) {
	logger.Debug("Enter SendSingleChatMessage")
	defer logger.Debug("Exit SendSingleChatMessage")

	isOnline, onlineInfo := IsUserOnline(req.AppId, req.RecieverId)
	if !isOnline {
		// 离线消息存储
		if ok, err := storeOfflineSingleChatMessage(req); !ok {
			code = common.StoreError
			errReturn = err
			deleteSingleChatMessage(req)
			return
		}
		code = common.OK
		errReturn = nil
		return
	}

	isLocalUser := IsUserLocal(onlineInfo)
	// 非本机用户，远程grpc发送消息
	if !isLocalUser {
		if ok, err := sendSingleChatMessageRemote(req, onlineInfo); !ok {
			code = common.RemoteCallError
			errReturn = err
			deleteSingleChatMessage(req)
			return
		}

		code = common.OK
		errReturn = nil
		return
	}

	// 本机用户，在线本地发送消息
	if ok, err := SendSingleChatMessageLocal(req); !ok {
		code = common.LocalCallError
		errReturn = err
		deleteSingleChatMessage(req)
		return
	}

	code = common.OK
	errReturn = nil
	return
}

// 判断是否是好友
func isSingleFriend(SenderId, RecieverId int64) (ok bool, err error) {
	return model.IsSingleFriend(SenderId, RecieverId)
}

// 持久化一条单聊消息mysql
func persistSingleChatMessage(req *common.WsSingleChatRequest) (id int64, err error) {
	return model.NewSingleMessage(req.AppId, req.Type, req.Content, req.SenderId, req.RecieverId, req.SentTime)
}

// 删除一条单聊消息mysql
func deleteSingleChatMessage(req *common.WsSingleChatRequest) (ok bool, err error) {
	return model.DeleteSingleMessage(req.Id)
}

// 给本机用户发送单聊消息ws
func SendSingleChatMessageLocal(req *common.WsSingleChatRequest) (ok bool, err error) {
	recieverConn := connection.GetUserConnection(req.AppId, req.RecieverId)
	if recieverConn == nil {
		ok, err = false, nil
		return
	}

	data, err := json.Marshal(req)
	if err != nil {
		ok = false
		return
	}

	recieverConn.SendMessage(data)
	ok = true
	return
}

// 给非本机用户发送单聊消息grpc
func sendSingleChatMessageRemote(req *common.WsSingleChatRequest, info *model.UserOnline) (ok bool, err error) {
	// 通过接收者online信息中的其所在的rpc server name来发送信息给接收者
	if err = grpcclient.SendSingleChatMsg(info.RpcServerName, req); err != nil {
		ok = false
		return
	}

	ok = true
	return
}

// 离线存储单聊消息redis
func storeOfflineSingleChatMessage(req *common.WsSingleChatRequest) (ok bool, err error) {
	data, err := json.Marshal(req)
	if err != nil {
		ok = false
		return
	}

	if err = library.StoreOfflineSingleChatMsg(req.RecieverId, string(data), float64(req.SentTime)); err != nil {
		logger.Debug("消息发送失败-离线存储失败", req.AppId, req.RecieverId, err)
		ok = false
		return
	}

	logger.Debug("用户不在线, 消息已离线存储", req.AppId, req.RecieverId, err)
	ok = true
	return
}

// 单聊消息接收者发送ack给发送者
/*
func AckSingleChat(req *common.WsSingleChatAck) (sendResult SendResult, errReturn error) {
	logger.Debug("Enter AckSingleChat")
	defer logger.Debug("Exit AckSingleChat")

	// 验证好友关系
	if ok, err := isSingleFriend(req.SenderId, req.RecieverId); !ok {
		sendResult.Success = false
		errReturn = err
		return
	}

	// 历史ack消息存储
	msgId, err := persistSingleChatAck(req)
	if err != nil {
		sendResult.Success = false
		errReturn = err
		return
	}
	sendResult.MsgId = msgId

	// 在线本地发送ack消息
	if ok, _ := SendSingleChatAckLocal(req); !ok {
		// 在线远程发送ack消息
		if ok, _ := sendSingleChatAckRemote(req); !ok {
			// 离线ack消息存储
			if ok, err := storeOfflineSingleChatAck(req); !ok {
				sendResult.Success = false
				errReturn = err
				deleteSingleChatMessage(req)
			}
			sendResult.Success = false
			errReturn = nil
			return
		}
	}

	sendResult.Success = true
	errReturn = nil
	return
}*/
